// 导入类型定义
import { BehaviorInfo, SDKConfig } from '../types'; // 导入行为信息和SDK配置类型
import { 
  getCurrentUrl, // 获取当前页面URL
  getElementSelector, // 获取元素选择器
  getElementText, // 获取元素文本
  shouldSample, // 判断是否采样
  throttle, // 节流函数
  debounce // 防抖函数
} from '../utils'; // 导入工具函数

// 行为监控器类，负责采集用户行为数据
export class BehaviorMonitor {
  private config: SDKConfig; // SDK配置
  private behaviorHandler: (behavior: BehaviorInfo) => void; // 行为数据处理回调
  private isInitialized = false; // 是否已初始化

  // 构造函数，传入配置和回调
  constructor(config: SDKConfig, behaviorHandler: (behavior: BehaviorInfo) => void) {
    this.config = config; // 保存配置
    this.behaviorHandler = behaviorHandler; // 保存回调
  }

  // 初始化行为监控
  public init(): void {
    if (this.isInitialized) {
      return; // 已初始化则直接返回
    }
    this.isInitialized = true; // 标记为已初始化
    this.setupClickHandler(); // 监听点击事件
    this.setupScrollHandler(); // 监听滚动事件
    this.setupInputHandler(); // 监听输入事件
    this.setupNavigationHandler(); // 监听导航事件
  }

  // 设置点击事件处理器
  private setupClickHandler(): void {
    // 节流处理点击事件，1秒内只记录一次
    const throttledClickHandler = throttle((event: MouseEvent) => {
      if (!shouldSample(this.config.sampleRate)) {
        return; // 不采样则返回
      }
      const target = event.target as Element; // 获取事件目标
      if (!target) return; // 无目标则返回
      const behaviorInfo: BehaviorInfo = {
        type: 'click', // 行为类型
        selector: getElementSelector(target), // 元素选择器
        text: getElementText(target), // 元素文本
        url: getCurrentUrl(), // 当前URL
        timestamp: Date.now(), // 时间戳
        extra: {
          x: event.clientX, // 鼠标X坐标
          y: event.clientY, // 鼠标Y坐标
          button: event.button, // 鼠标按键
          ctrlKey: event.ctrlKey, // Ctrl键
          shiftKey: event.shiftKey, // Shift键
          altKey: event.altKey, // Alt键
          metaKey: event.metaKey // Meta键
        }
      };
      this.behaviorHandler(behaviorInfo); // 上报行为数据
    }, 1000); // 1秒节流
    document.addEventListener('click', throttledClickHandler, true); // 捕获阶段监听点击
  }

  // 设置滚动事件处理器
  private setupScrollHandler(): void {
    // 防抖处理滚动事件，500ms内只记录一次
    const debouncedScrollHandler = debounce((event: Event) => {
      if (!shouldSample(this.config.sampleRate)) {
        return; // 不采样则返回
      }
      const target = event.target as Element;
      if (!target || (target instanceof HTMLElement && target.id === 'log')) return; // 忽略日志区域
      const behaviorInfo: BehaviorInfo = {
        type: 'scroll', // 行为类型
        selector: getElementSelector(target), // 元素选择器
        url: getCurrentUrl(), // 当前URL
        timestamp: Date.now(), // 时间戳
        extra: {
          scrollTop: (target as HTMLElement).scrollTop || 0, // 滚动条顶部
          scrollLeft: (target as HTMLElement).scrollLeft || 0, // 滚动条左侧
          scrollHeight: (target as HTMLElement).scrollHeight || 0, // 滚动区域高度
          scrollWidth: (target as HTMLElement).scrollWidth || 0, // 滚动区域宽度
          clientHeight: (target as HTMLElement).clientHeight || 0, // 可视区域高度
          clientWidth: (target as HTMLElement).clientWidth || 0 // 可视区域宽度
        }
      };
      this.behaviorHandler(behaviorInfo); // 上报行为数据
    }, 500); // 500ms防抖
    // 只监听 window 的 scroll
    window.addEventListener('scroll', debouncedScrollHandler, true);
  }

  // 设置输入事件处理器
  private setupInputHandler(): void {
    // 防抖处理输入事件，1秒内只记录一次
    const debouncedInputHandler = debounce((event: Event) => {
      if (!shouldSample(this.config.sampleRate)) {
        return; // 不采样则返回
      }
      const target = event.target as HTMLInputElement | HTMLTextAreaElement; // 获取输入目标
      if (!target) return; // 无目标则返回
      const behaviorInfo: BehaviorInfo = {
        type: 'input', // 行为类型
        selector: getElementSelector(target), // 元素选择器
        text: target.value ? target.value.substring(0, 50) : '', // 只记录前50个字符
        url: getCurrentUrl(), // 当前URL
        timestamp: Date.now(), // 时间戳
        extra: {
          inputType: target.type, // 输入类型
          placeholder: target.placeholder || '', // 占位符
          maxLength: target.maxLength || -1, // 最大长度
          valueLength: target.value.length // 当前值长度
        }
      };
      this.behaviorHandler(behaviorInfo); // 上报行为数据
    }, 1000); // 1秒防抖
    document.addEventListener('input', debouncedInputHandler, true); // 捕获阶段监听输入
  }

  // 设置页面导航处理器
  private setupNavigationHandler(): void {
    // 监听 history.pushState
    const originalPushState = history.pushState; // 保存原始方法
    const originalReplaceState = history.replaceState; // 保存原始方法
    const self = this; // 保存this指针
    history.pushState = function(data: any, title: string, url?: string | URL | null) {
      // 使用call绑定this提供上下文环境
      const result = originalPushState.call(this, data, title, url); // 调用原始方法
      if (shouldSample(self.config.sampleRate)) {
        const behaviorInfo: BehaviorInfo = {
          type: 'navigation', // 行为类型
          url: getCurrentUrl(), // 当前URL
          timestamp: Date.now(), // 时间戳
          extra: {
            navigationType: 'pushState', // 导航类型
            state: data, // 状态数据
            title: title, // 标题
            url: url // 目标URL
          }
        };
        self.behaviorHandler(behaviorInfo); // 上报行为数据
      }
      return result; // 返回原始结果
    };
    // 监听 history.replaceState
    history.replaceState = function(data: any, title: string, url?: string | URL | null) {
      const result = originalReplaceState.call(this, data, title, url); // 调用原始方法
      if (shouldSample(self.config.sampleRate)) {
        const behaviorInfo: BehaviorInfo = {
          type: 'navigation', // 行为类型
          url: getCurrentUrl(), // 当前URL
          timestamp: Date.now(), // 时间戳
          extra: {
            navigationType: 'replaceState', // 导航类型
            state: data, // 状态数据
            title: title, // 标题
            url: url // 目标URL
          }
        };
        self.behaviorHandler(behaviorInfo); // 上报行为数据
      }
      return result; // 返回原始结果
    };
    // 监听浏览器前进后退
    window.addEventListener('popstate', (event) => {
      if (!shouldSample(this.config.sampleRate)) {
        return; // 不采样则返回
      }
      const behaviorInfo: BehaviorInfo = {
        type: 'navigation', // 行为类型
        url: getCurrentUrl(), // 当前URL
        timestamp: Date.now(), // 时间戳
        extra: {
          navigationType: 'popstate', // 导航类型
          state: event.state // 状态数据
        }
      };
      this.behaviorHandler(behaviorInfo); // 上报行为数据
    });
  }

  // 手动上报用户行为
  public reportBehavior(behavior: BehaviorInfo): void {
    if (!shouldSample(this.config.sampleRate)) {
      return; // 不采样则返回
    }
    this.behaviorHandler(behavior); // 上报行为数据
  }

  // 销毁行为监控器，移除所有事件监听
  public destroy(): void {
    this.isInitialized = false; // 标记为未初始化
    // 移除事件监听（注意：这里只是示意，实际移除需保存回调引用）
    document.removeEventListener('click', this.setupClickHandler);
    document.removeEventListener('scroll', this.setupScrollHandler);
    document.removeEventListener('input', this.setupInputHandler);
    window.removeEventListener('popstate', this.setupNavigationHandler);
  }
} 